package com.wwcom.darteagle.fragment;

import java.util.List;

import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;

import com.wwcom.darteagle.R;
import com.wwcom.darteagle.data.DartEagleDatabase;
import com.wwcom.darteagle.model.DartStats;
import com.wwcom.darteagle.model.GlobalAppData;
import com.wwcom.darteagle.model.Leg;
import com.wwcom.darteagle.model.Match;
import com.wwcom.darteagle.model.Player;
import com.wwcom.darteagle.model.Set;
import com.wwcom.darteagle.view.MatchStatsPositionMarkerView;

public class StatsDetailsFragment extends Fragment {
	public static final int MAX_PLAYERS_ON_SCREEN= 2;
	public static final String MATCH_ID= "matchId";
	public static final String LEG_IND= "legInd";
	public static final String SET_IND= "setInd";
	public static final String PLAYER_ID= "playerId";
	public static final String NUM_IN_LIST= "numInList";
	public static final String POS_IN_LIST= "posInList";
	
	private Match match;
	private long matchId;
	private int legInd;
	private int setInd;
	private long playerId;
	LayoutInflater inflater;
	View v;
	ViewGroup container;
    	
	private final static int[] VIEW_IDS= {R.id.playerName,
		R.id.playerLegs,R.id.playerSets,
		R.id.playerAverage, R.id.playerFirst9Average,
		R.id.playerHighestScore,R.id.player60Plus,
		R.id.player100Plus,R.id.player140Plus,R.id.player180Plus,
		R.id.playerHighestCheckout,R.id.playerDoubles,R.id.playerCheckouts,
		R.id.player50PlusCheckout,R.id.player100PlusCheckout,
		R.id.playerAccuracy20,R.id.playerAccuracy19,
		R.id.playerPercentage20,R.id.playerPercentage19
	};

	/** Called when the fragment is first created. */	
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
            Bundle savedInstanceState) {
		 
    	this.inflater= inflater;
        //if matchId is -1 then we are displaying the current match, 
    	// if it is -2 then we display a players overall stats,
    	// otherwise a specific database id is passed
        matchId= -1;
    	legInd= -1;
    	setInd= -1;
    	playerId= -1;

    	//arguments or saved state
        Bundle args = this.getArguments();
        if(args != null) {
        	legInd= args.getInt(LEG_IND);
        	setInd= args.getInt(SET_IND);
        	matchId= args.getLong(MATCH_ID);
        	Log.d("StatsDetailsFragment","Arguments - matchId: "+matchId+", legInd: "+legInd+", setInd: "+setInd);
        	if (matchId == -2) { 
        		playerId= args.getLong(PLAYER_ID);
        		Log.d("StatsDetailsFragment","Arguments - playerId: "+playerId);
        	}
        }
        
        //recover saved state
        if (savedInstanceState != null) {
        	legInd= savedInstanceState.getInt(LEG_IND);
        	setInd= savedInstanceState.getInt(SET_IND);
        	matchId= savedInstanceState.getLong(MATCH_ID);
        	playerId= savedInstanceState.getLong(MATCH_ID);
        	Log.d("StatsDetailsFragment","SavedState - matchId: "+matchId+", legInd: "+legInd+", setInd: "+setInd);
		}        
    	Log.d("StatsDetailsFragment","onCreateView - matchId: "+matchId+", legInd: "+legInd+", setInd: "+setInd);
        
        //load match
        GlobalAppData gd= GlobalAppData.getSingletonInstance();
        Player player= null;
        if (matchId >= -1) {
        	match= gd.getMatch(matchId, getActivity());
        } else {
    		DartEagleDatabase db= new DartEagleDatabase(getActivity());  
    		player= db.getPlayer(playerId);
    		match= db.getPlayerOverallMatch(player);
    		db.close();
        }
        
    	this.container= container;
    	if (match.getMatchPlayers().size() <= MAX_PLAYERS_ON_SCREEN) {
    		this.v= inflater.inflate(R.layout.matchstats_fragment_noscroll, container, false);
    	} else {
    		this.v= inflater.inflate(R.layout.matchstats_fragment, container, false);
    	}
    	
        setupViews(legInd,setInd);
        
        //setup title
        if (matchId == -2) {
        	((TextView)v.findViewById(R.id.matchstats_title)).setText(
        			getString(R.string.matchstats_player_overall_statistics,player.getName()));        	        	
        } else if (legInd >= 0 && setInd >=0) {
        	((TextView)v.findViewById(R.id.matchstats_title)).setText(
        			getString(R.string.matchstats_set_leg_statistics,(setInd+1),(legInd+1)));        	
        } else if (legInd >= 0) {        	
        	((TextView)v.findViewById(R.id.matchstats_title)).setText(
        			getString(R.string.matchstats_leg_statistics,(legInd+1)));
        } else if (setInd >= 0) {
        	((TextView)v.findViewById(R.id.matchstats_title)).setText(
        			getString(R.string.matchstats_set_statistics,(setInd+1)));
        }
                
        //setup list markers
    	int numInList= args.getInt(NUM_IN_LIST);
    	int posInList= args.getInt(POS_IN_LIST);
        
    	MatchStatsPositionMarkerView markerView= (MatchStatsPositionMarkerView)v.findViewById(R.id.matchstats_position_marker);
    	if (numInList > 1) {
    		markerView.setNumInList(numInList);
    		markerView.setPosInList(posInList);
    	} else {   //hide if we don't need it
			//LayoutParams lp= new LayoutParams(LayoutParams.MATCH_PARENT,0);
    		//markerView.setLayoutParams(lp);
    	}
        return this.v;
    }
        
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
      super.onSaveInstanceState(savedInstanceState);
      // Save UI state changes to the savedInstanceState.
      // This bundle will be passed to onCreate if the process is
      // killed and restarted.
  	  savedInstanceState.putLong(MATCH_ID,matchId);
  	  savedInstanceState.putInt(LEG_IND,legInd);
  	  savedInstanceState.putInt(SET_IND,setInd);
  	  savedInstanceState.putLong(PLAYER_ID,playerId);  	  
    }    
    
    private void setupViews(int legInd, int setInd) {
    	
    	//work in DP units correctly respecting device DPI
	    @SuppressWarnings("deprecation")
		int displayWidthActual= getActivity().getWindowManager().getDefaultDisplay().getWidth();
        DisplayMetrics metrics = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
        float dpFac= metrics.densityDpi / 160.0f;
        int displayWidthDP= (int)((float)displayWidthActual / dpFac);
	    int widthForColumnsDP= displayWidthDP-100; //header column is 100dp
	    int colWidthDP= widthForColumnsDP / MAX_PLAYERS_ON_SCREEN;
	    int nPlayers= match.getMatchPlayers().size(); 
	    if (nPlayers < MAX_PLAYERS_ON_SCREEN)
	    	colWidthDP= widthForColumnsDP;
	    int colWidthActual= (int) ((float)colWidthDP * dpFac); 	    	
	    
		//hide sets if required
		if (matchId != -2 && match.getNumSets() == 0) {
			TableRow tr= (TableRow)v.findViewById(R.id.playerSets);
			TableRow.LayoutParams lp2= new TableRow.LayoutParams(LayoutParams.MATCH_PARENT,1);
			tr.setLayoutParams(lp2);
			tr.removeAllViews();
			tr.invalidate();
		}
	    
        //float weight= 1.0f/(float)match.getMatchPlayers().size();
        TableRow.LayoutParams lp= new TableRow.LayoutParams(colWidthActual,LayoutParams.WRAP_CONTENT);
        List<DartStats> dsList= match.getPlayerStats();
        if (legInd >= 0) {
        	Log.d("StatsDetailsFragment","SetInd: "+setInd+", "+legInd);
			dsList= match.getPlayerStatsLeg(setInd,legInd);
		} else if (setInd >= 0) {
			dsList= match.getPlayerStatsSet(setInd);			
		}
		for (int viewId : VIEW_IDS) {
			//don't display sets for a match with no sets 
			if (viewId == R.id.playerSets && matchId != -2 && match.getNumSets()==0)
				continue;
			TableRow tr= (TableRow)v.findViewById(viewId);
			TextView label= (TextView)tr.getChildAt(0);
			setViewTouch(label, viewId);
			for (DartStats ds : dsList) {
				TextView v= (TextView)inflater.inflate(R.layout.matchstats_textview, null);
				v.setLayoutParams(lp);
				setViewText(v,ds,viewId);				
				tr.addView(v);
			}
        }
		
		//doubles table
		TableLayout tl= (TableLayout)v.findViewById(R.id.doubles_table);		
		for (int i=0 ; i<21; i++) {
			TableRow tr= (TableRow)inflater.inflate(R.layout.matchstats_tablerow, null);
			TextView title= (TextView)tr.findViewById(R.id.accuracy_title);
			if (i<20)
				title.setText(getString(R.string.matchstats_doubles_title,i+1));
			else
				title.setText("Bull %:");

			for (DartStats ds : dsList) {
				TextView v= (TextView)inflater.inflate(R.layout.matchstats_textview, null);
				v.setLayoutParams(lp);
	    		v.setText(String.format("%.02f%%\n(%d of %d)",
	        			ds.getIndividualDoublePercentage(i),
	        			ds.getIndividualDoubleSuccesses(i),
	        			ds.getIndividualDoubleAttempts(i)));
				tr.addView(v);
			}
							
			tl.addView(tr);
		}
    			
    }
    
    private void setViewText(TextView v, DartStats ds, int viewId) {
    	switch(viewId) {
    	case R.id.playerName:
    		v.setText(ds.getMatchPlayer().getPlayer().getName().toUpperCase());
    		v.setTypeface(Typeface.DEFAULT_BOLD); 
    		break;    		
    	case R.id.playerLegs:
    		if (matchId == -2) {
				v.setText(Integer.toString(ds.getMatchPlayer().getNumLegs()));
    		} else if (legInd == -1 && setInd == -1) { //match
    			if (match.getNumSets() > 0) { //sets match
    				int numLegs= 0;
    				for (Set s : match.getSets()) {
    	    			for (Leg l : s.getLegs()) {
    	    				if (l.getLegWinner() != null &&
    	    						l.getLegWinner().getPlayer() == ds.getMatchPlayer().getPlayer()) {
    	    	    			numLegs++;   					
    	    				}
    	    			}
    				}
    				v.setText(Integer.toString(numLegs));
    			} else {
    				v.setText(Integer.toString(ds.getMatchPlayer().getNumLegs()));
    			}
    		} else if (legInd == -1 && setInd >= 0) { //set
    			List<Set> sets= match.getSets();
    			int numLegs= 0;
	    		for (Leg l : sets.get(setInd).getLegs()) {
	    			if (l.getLegWinner() != null &&
	    					l.getLegWinner().getPlayer() == ds.getMatchPlayer().getPlayer()) {
	    	    		numLegs++;   					
	    			}
	    		}
				v.setText(Integer.toString(numLegs));
    		} else if (legInd >= 0 && setInd >= 0){ //leg in set
    			List<Set> sets= match.getSets();
    			List<Leg> legs= sets.get(setInd).getLegs();
    			if (legs.get(legInd).getLegWinner() != null &&
    					legs.get(legInd).getLegWinner().getPlayer() == ds.getMatchPlayer().getPlayer())
	    			v.setText("1");
	    		else
	    			v.setText("0");
    		} else { //leg in match
    			List<Leg> legs= match.getLegs();
    			if (legs.get(legInd).getLegWinner() != null &&
    					legs.get(legInd).getLegWinner().getPlayer() == ds.getMatchPlayer().getPlayer())
	    			v.setText("1");
	    		else
	    			v.setText("0");    			
    		}
    		v.setTypeface(Typeface.DEFAULT_BOLD); 
    		break;    		
    	case R.id.playerSets:
    		if (matchId == -2) {
				v.setText(Integer.toString(ds.getMatchPlayer().getNumSets()));
    		} else if (setInd == -1 && legInd == -1) { //match
    			v.setText(Integer.toString(ds.getMatchPlayer().getNumSets()));
    		} else if(setInd >=0 && legInd == -1) { //set
    			List<Set> sets= match.getSets();
    			if (sets.get(setInd).getSetWinner() != null &&
    					sets.get(setInd).getSetWinner().getPlayer() == ds.getMatchPlayer().getPlayer())
	    			v.setText("1");
	    		else
	    			v.setText("0");    			
    		} else { //leg
    			v.setText("0");    			    			
    		}
    		v.setTypeface(Typeface.DEFAULT_BOLD); 
    		break;    		
    	case R.id.playerFirst9Average:
    		v.setText(String.format("%.02f",ds.getFirst9Average()*3.0f));
    		break;
    	case R.id.playerAverage:    		
    		v.setText(String.format("%.02f",ds.getAverage()*3.0f));
    		break;
    	case R.id.playerHighestScore:    		    		
    		v.setText(Integer.toString(ds.getHighestScore()));
    		break;
    	case R.id.player60Plus:    		    		    		
    		v.setText(Integer.toString(ds.getPlus60()));
    		break;
    	case R.id.player100Plus:    		    		    		
    		v.setText(Integer.toString(ds.getPlus100()));
    		break;
    	case R.id.player140Plus:    		    		    		
    		v.setText(Integer.toString(ds.getPlus140()));
    		break;
    	case R.id.player180Plus:    		    		    		
    		v.setText(Integer.toString(ds.getPlus180()));
    		break;
    	case R.id.playerHighestCheckout:    		    		    		
    		v.setText(Integer.toString(ds.getHighestCheckout()));
    		break;
    	case R.id.playerDoubles:    		    		    		
    		v.setText(String.format("%.02f%%\n(%d of %d)",
    			ds.getDoublePercentage(),ds.getDoubleSuccesses(),ds.getDoubleAttempts()));
    		break;
    	case R.id.playerCheckouts:    		    		    		
    		v.setText(String.format("%.02f%%\n(%d of %d)",
    			ds.getCheckoutPercentage(),ds.getCheckoutSuccesses(),ds.getCheckoutAttempts()));
    		break;
    	case R.id.player50PlusCheckout:    		    		    		
    		v.setText(Integer.toString(ds.getPlus50Checkout()));
    		break;
    	case R.id.player100PlusCheckout:    		    		    		
    		v.setText(Integer.toString(ds.getPlus100Checkout()));
    		break;
    	case R.id.playerPercentage20:    		    		    		
    		v.setText(String.format("%.02f%%\n(%d of %d)",
    			ds.getAccuracy20Percentage(),ds.getAccuracy20Successes(),ds.getAccuracy20Attempts()));
    		break;
    	case R.id.playerPercentage19:    		    		    		
    		v.setText(String.format("%.02f%%\n(%d of %d)",
    			ds.getAccuracy19Percentage(),ds.getAccuracy19Successes(),ds.getAccuracy19Attempts()));
    		break;
    	case R.id.playerAccuracy20:    		    		    		
    		v.setText(String.format("%.02f\n(max 100)",
    			ds.getAccuracy20Rating()));
    		break;
       	case R.id.playerAccuracy19:    		    		    		
        	v.setText(String.format("%.02f\n	(max 100)",
        		ds.getAccuracy19Rating()));
        	break;
    	
    	}
        
    }
    
    private void setViewTouch(TextView v, final int viewId) {   	
    	switch(viewId) {
    	case R.id.playerFirst9Average:
    	case R.id.playerAverage:    		
    	case R.id.player60Plus:    		    		    		
    	case R.id.player100Plus:    		    		    		
    	case R.id.player140Plus:    		    		    		
    	case R.id.player180Plus:    		    		    		
    	case R.id.playerDoubles:    		    		    		
    	case R.id.playerCheckouts:    		    		    		
    	case R.id.playerPercentage20:    		    		    		
    	case R.id.playerPercentage19:    		    		    		
    	case R.id.playerAccuracy20:    		    		    		
       	case R.id.playerAccuracy19:
       		v.setPaintFlags(v.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
       		v.setClickable(true);
    		v.setOnClickListener(new OnClickListener() {
    		    public void onClick(View v2) {
   		        	showStatDescription(viewId);
    		    }
    		});   
    		break;
    	}
        
    }
    
    private void showStatDescription(int viewId) {
    	int descriptionId= 0;
    	switch(viewId) {
    	case R.id.playerFirst9Average:
    		descriptionId= R.string.matchstats_first_nine_descrption;
    		break;
    	case R.id.playerAverage:    		
    		descriptionId= R.string.matchstats_average_descrption;
    		break;
    	case R.id.player60Plus:    		    		    		
    		descriptionId= R.string.matchstats_60_plus_description;
    		break;
    	case R.id.player100Plus:    		    		    		
    		descriptionId= R.string.matchstats_100_plus_description;
    		break;
    	case R.id.player140Plus:    		    		    		
    		descriptionId= R.string.matchstats_140_plus_description;
    		break;
    	case R.id.player180Plus:    		    		    		
    		descriptionId= R.string.matchstats_180s_description;
    		break;
    	case R.id.playerDoubles:    		    		    		
    		descriptionId= R.string.matchstats_doubles_percentage_description;
    		break;
    	case R.id.playerCheckouts:    		    		    		
    		descriptionId= R.string.matchstats_checkout_percentage_description;
    		break;
    	case R.id.playerPercentage20:    		    		    		
    		descriptionId= R.string.matchstats_accuracy_percentage20_description;
    		break;
    	case R.id.playerPercentage19:    		    		    		
    		descriptionId= R.string.matchstats_accuracy_percentage19_description;
    		break;
    	case R.id.playerAccuracy20:    		    		    		
    		descriptionId= R.string.matchstats_accuracy20_description;
    		break;
       	case R.id.playerAccuracy19:    		    		    		
    		descriptionId= R.string.matchstats_accuracy19_description;
    		break;
    	}
    	if (descriptionId > 0) {
    		Toast t = Toast.makeText(getActivity(), getString(descriptionId), Toast.LENGTH_LONG);
    		t.setGravity(Gravity.CENTER|Gravity.CENTER, 0, 0);
    		t.show();
    	}
    	
    }
 
}